home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************
- *
- * DRAWER.C
- *
- **************************************************************/
-
- #include <acs.h>
- #include <acsplus.h>
- #include <stdlib.h>
- #include <string.h>
- #include <messages.pif>
- #include <acs_plus.pif>
- #include <graphics.pif>
- #include <notimtab.pif>
- #include "..\filter\filter.pif"
- #include "..\params\params.pif"
- #include "..\info\info.pif"
-
- #include "drawer.pif"
- #include "drawer.h"
- #include "drawer.ah"
-
- #define MAX_NOTE_HEIGHT 127
-
- #define HEADLINE_DIVIDER 3 /* headl.height = syst.dist./HEADLINE_DIVIDER */
- #define INDEX_CHARACTERS 2 /* max. number of characters for index */
-
-
- /************* OBJECT DATA PROTOTYPE BEGIN ***********************/
-
-
- #define HEADLINE_HEIGHT 12 /* [points] */
- #define INDEX_HEIGHT 8 /* [points] */
- #define TRACK_HEIGHT 8 /* [points] */
-
- /*** possible values for page type ***/
-
- #define NO 0x00 /* no valid type */
- #define MULTIPLE 0x01 /* one or more whole note systems fit onto this page */
- #define PRECEEDING 0x02 /* the tail of the system is on a succeeding page */
- #define SUCCEEDING 0x04 /* the head of the system is on a preceeding page */
-
- typedef struct
- {
- char number_of_systems ; /* on this page */
- char type ; /* see above */
- int first_track, last_track ; /* to be drawn for this page */
- TIME min_time ; /* in ticks */
- }
- PAGE_DESCRIPTOR ;
-
- #define MAX_PAGES 200
-
- typedef struct
- {
- /*** init only data ***/
-
- int handle ; /* of VDI workstation */
- Awindow *obj_wi ; /* window of GEM-object to be drawn */
- int obj ; /* index of GEM-object to be drawn */
- int width, height ; /* of GEM-object */
- Awindow *params_wi, /* related object instances */
- *filter_wi, /* for access to their hidden data */
- *info_wi ;
- int ntrks ; /* number of tracks to be treated */
-
- /*** read/write data ***/
-
- int font_id ;
- int current_page ; /* number of page that shall be displayed */
- int npgs ; /* number of pages with valid layout */
- PAGE_DESCRIPTOR page[MAX_PAGES] ; /* drawing layout for all pages */
- int x_min, x_max, y_min, y_max ; /* maximum area allowed for whole drawing */
- int x_min_systems, x_max_systems, /* same for drawing note systems */
- y_min_systems, y_max_systems ;
- float dy_system, dy_track ;
- float dy_note, dy_line ; /* y-distances */
- float dx_bars ; /* x-distance */
- float beats_per_system ; /* quarter beats */
- int bars_per_system ;
- char bar_divider ;
- TIME time_per_system ; /* in ticks per system */
- }
- DRAWER ;
-
- /************* OBJECT DATA PROTOTYPE END *************************/
-
-
- /*******************************************************************
- */
- static void keys(Awindow *wi, int kstate, int key)
-
- /* Keyboard procedure of the drawer window. See ACS manual.
- *
- *******************************************************************/
- {
- /*** delayed update ***/
- if (set_timer(wi) == -1) Awi_sendall(REDRAW, wi) ;
-
- /*** inform other windows about key pressure ***/
- key_message.sender = wi ;
- key_message.kstate = kstate ;
- key_message.key = key ;
- Awi_sendall(KEY_PRESS, &key_message) ;
-
- /*** forward event to ACS for further treatment (e.g. by the desktop) ***/
- Awi_keys(wi, kstate, key) ;
- }
-
- /*******************************************************************
- */
- static int service(Awindow *wi, int task, void *not_used)
-
- /* Service routine for messages sent to this window. See ACS manual.
- *
- * OUTPUT: AS_TERM ==> message is forwarded to parent
- * AS_INFO ==> a little help function
- *
- * RETURN: TRUE: if task could be treated
- * FALSE: else
- *
- *******************************************************************/
- {
- switch (task)
- {
- case AS_TERM: Awi_sendall(TERMINATE, wi) ; break ;
- case AS_INFO: A_dialog(&DRAWER_INFO) ; break ;
- default: return FALSE ;
- }
- return TRUE ;
- }
-
- /************/
- void expand /*
- *************/
- (
- char lines_per_12, /* IN: so many horizontal lines are used per 12 notes */
- NOTE min_note, /* IN: marks the minimum of the range to be expanded */
- NOTE max_note, /* IN: marks the maximum of the range to be expanded */
- NOTE *note_of_first_line , /* OUT: first note of the expanded range */
- char *number_of_lines, /* OUT: the expanded range consists of n*(*number_of_lines) notes */
- char *first_modulo_0 /* OUT: indicates the first line with note mod m == 0 */
- )
- {
- char notes_per_line = 12 / lines_per_12 ;
- *note_of_first_line = min_note / notes_per_line * notes_per_line ;
-
- *number_of_lines = (max_note - *note_of_first_line + notes_per_line - 1) /
- notes_per_line + 1 ;
- *first_modulo_0 = (lines_per_12 - *note_of_first_line % 12 / notes_per_line) %
- lines_per_12 ;
- }
-
- /*************************/
- static void button(void) /*
- **************************/
- {
- switch (ev_obnr)
- {
- case FIRST: select_page(ev_window, first) ; break ;
- case PREVIOUS: select_page(ev_window, previous) ; break ;
- case NEXT: select_page(ev_window, next) ; break ;
- case LAST: select_page(ev_window, last) ; break ;
- case ZOOM_IN: Awi_sendall(ZOOM_PLUS, ev_window) ; break ;
- case ZOOM_OUT: Awi_sendall(ZOOM_MINUS, ev_window) ; break ;
- }
- }
-
- /*******************************************************************
- *
- * PUBLISHED INTERFACE
- *
- *******************************************************************/
-
-
- void select_page(Awindow *wi, SELECT_MODE sm)
- {
- DRAWER *d = wi->user ;
- char *text ;
-
- /*** determine page to be drawn ***/
- if (sm == first) d->current_page = 0 ;
- if (sm == previous)
- {
- if (d->current_page > 0) d->current_page -- ;
- else
- {
- alert_str(FIRST_PAGE, "") ;
- return ;
- }
- }
- if (sm == next)
- {
- if (d->current_page < d->npgs - 1) d->current_page ++ ;
- else
- {
- alert_str(LAST_PAGE, "") ;
- return ;
- }
- }
- if (sm == last) d->current_page = d->npgs - 1 ;
- if (d->current_page > d->npgs - 1) d->current_page = d->npgs - 1 ;
-
- /*** refresh page number in the GEM-object ***/
- text = wi->work[PAGE].ob_spec.tedinfo->te_ptext ;
- if (d->current_page < 100)
- {
- text[0] = '0' ;
- text++ ;
- }
- if (d->current_page < 10)
- {
- text[0] = '0' ;
- text++ ;
- }
- itoa( d->current_page, text, 10) ;
- Awi_obchange(wi, PAGE, -1) ;
-
- /*** draw with new parameters ***/
- if (sm != same) redraw(wi) ;
- }
-
-
- int get_first_page(Awindow *wi)
- { return 0 ; }
-
-
- int get_last_page(Awindow *wi)
- { return ((DRAWER *)wi->user)->npgs - 1 ; }
-
-
- static int DRAWER_init(Awindow *wi)
- {
- select_page(wi, same) ;
- return OK ;
- }
-
- int get_current_page(Awindow *wi)
- {
- DRAWER *d = wi->user ;
-
- d->current_page = atoi(wi->work[PAGE].ob_spec.tedinfo->te_ptext) ;
- if (d->current_page > d->npgs - 1) d->current_page = d->npgs - 1 ;
- wi->state |= AWS_LATEUPDATE ; /* call DRAWER_init() later */
- return d->current_page ;
- }
-
-
- void redraw(Awindow *wi)
- {
- DRAWER *d = wi->user ;
-
- /*** layout all pages ***/
- if ( page_layouter(d->handle, d->width, d->height, wi) == LAYOUT_ERR )
- return ;
- /*** refresh target object ***/
- Awi_obchange(d->obj_wi, d->obj, (d->obj_wi)->work[d->obj].ob_state) ;
- }
-
-
- void draw_page(int handle, Awindow *wi, int x0, int y0, int *points,
- int zoom, int page)
- {
- DRAWER *d = wi->user ;
- PAGE_DESCRIPTOR *p = &d->page[page] ;
- TIME min_time, max_time ;
- NOTE min_note, max_note, note_of_y ;
- char *track_name, *text = "----" ;
- float y_min, y_max ;
- int system, track ;
- char number_of_lines, first_shadow ;
- int index_width, dummy ;
- int style[12], color[12], type, height, dynamic, mode ;
- MARK_MODE back_mode ;
- int hor_lines, back_style[12], back_color[12],
- black[12] = { 1,1,1,1,1,1,1,1,1,1,1,1 }, dots ;
- float dyn_scale ;
-
- if (d->npgs == 0) return ;
- vst_font(handle, d->font_id) ;
-
- /*** draw title and page number ***/
- if (y0 + d->y_min_systems * zoom > points[1])
- {
- vst_height(handle, (d->dy_system * zoom)/HEADLINE_DIVIDER,
- &dummy, &dummy, &dummy, &dummy) ;
- vst_alignment(handle, 1, 2, &dummy, &dummy) ;
- vst_effects(handle, get_text_effects(d->params_wi)) ;
- v_gtext(handle,
- x0 + ((d->x_min + d->x_max)>>1) * zoom,
- y0 + d->y_min * zoom,
- get_title(d->params_wi)) ;
- vst_alignment(handle, 2, 2, &dummy, &dummy) ;
- vst_effects(handle, NORMAL) ;
- v_gtext(handle, x0 + d->x_max * zoom, y0 + d->y_min * zoom,
- itoa(page, text, 10)) ;
- }
- /*** fetch note parameters and normalize ***/
- get_style_params(d->params_wi,
- style, color, &type, &height, &dynamic,
- back_style, back_color) ;
- hor_lines = get_hor_lines(d->params_wi) ;
- mode = get_mode(d->params_wi) ;
- height = ( d->dy_note * (height + 1) )/5 ;
- dyn_scale = ( (float)dynamic ) / 10 ;
-
- /*** draw note system(s) ***/
- y_min = y_max = d->y_min_systems ;
- if (p->type & SUCCEEDING) y_max += d->dy_track ;
- for (system = 0 ; system < p->number_of_systems ; system ++)
- {
- min_time = p->min_time + system * d->time_per_system ;
- max_time = min_time + d->time_per_system ;
- for (track = p->first_track ; track <= p->last_track ; track++)
- {
- if ( get_min_max(d->filter_wi, track, min_time, max_time,
- &min_note, &max_note) )
- {
- expand(hor_lines, min_note, max_note,
- ¬e_of_y, &number_of_lines, &first_shadow) ;
- if (note_of_y > MAX_NOTE_HEIGHT) note_of_y = 1 ;
- y_max += d->dy_line * (number_of_lines - 1) ;
-
- /*** if track is visible (inside clipping area) ***/
- if ( ((y_max + d->dy_line) * zoom + y0 > points[1]) &&
- ((y_max - d->dy_line * (number_of_lines + 1)) * zoom + y0 < points[3]) )
- {
- /*** draw horizontal lines with index and shadow ***/
- vsl_type(handle, SOLID) ;
- vst_height(handle, 4 * zoom * d->dy_note, &index_width, &dummy, &dummy, &dummy) ;
- vst_alignment(handle, 2, 0, &dummy, &dummy) ;
- vsf_interior(handle, FIS_PATTERN) ;
- vsf_perimeter(handle, 0) ; /* no perimeter */
- dots = -1 /* no dots */ ; back_mode = behind ;
- if (mode == Rieder) back_mode = between ;
- else if (mode == Beyreuther)
- dots = d->bars_per_system * (d->bar_divider - 1) ;
- draw_lines(handle, number_of_lines, first_shadow, hor_lines,
- back_mode, back_style, back_color, (note_of_y + 11)/12, dots,
- - index_width, 0,
- x0 + d->x_min_systems * zoom, y0 + y_max * zoom,
- x0 + d->x_max_systems * zoom, y0 + y_max * zoom,
- 0, - d->dy_line * zoom) ;
- /*** draw track name ***/
- track_name = get_track_name(d->filter_wi, track) ;
- vst_alignment(handle, 0, 3, &dummy, &dummy) ;
- vswr_mode(handle, MD_TRANS) ;
- v_gtext(handle, x0 + d->x_min_systems * zoom,
- y0 + (y_max - (d->dy_line * (number_of_lines - 1)
- + d->dy_note * 2)) * zoom, track_name ) ;
- vswr_mode(handle, MD_REPLACE) ;
- /*** draw notes of the current track ***/
- vsl_color(handle, BLACK) ;
- vsf_perimeter(handle, 1) ; /* with perimeter */
- draw_track(handle, d->filter_wi, track,
- x0 + d->x_min_systems * zoom,
- x0 + d->x_max_systems * zoom,
- y0 + y_max * zoom, - d->dy_note * zoom,
- min_time, max_time,
- note_of_y, height * zoom, dyn_scale,
- type, style, color) ;
- }
- y_max += d->dy_track ;
- }
- }
- if ( (system != p->number_of_systems - 1) || !(p->type & PRECEEDING) )
- y_max -= d->dy_track ;
- if (mode != Beyreuther)
- {
- /*** draw dashed horizontal lines (sub-bars) ***/
- vsl_udsty(handle, 0x2222) ;
- vsl_type(handle, USERLINE) ;
- draw_lines(handle, (d->bars_per_system * d->bar_divider) + 1, -1, -1,
- back_mode, back_style, black, 0, -1, 0, 0,
- x0 + d->x_min_systems * zoom, y0 + y_min * zoom + 1,
- x0 + d->x_min_systems * zoom, y0 + y_max * zoom - 1,
- d->dx_bars/d->bar_divider * zoom, 0) ;
- }
- /*** draw solid vertical lines (bars) ***/
- vsl_type(handle, SOLID) ;
- draw_lines(handle, d->bars_per_system + 1, -1, -1,
- back_mode, back_style, black, 0, -1, 0, 0,
- x0 + d->x_min_systems * zoom, y0 + y_min * zoom + 1,
- x0 + d->x_min_systems * zoom, y0 + y_max * zoom - 1,
- d->dx_bars * zoom, 0) ;
- /*** draw bar number ***/
- vswr_mode(handle, MD_TRANS) ;
- vst_alignment(handle, 2, 3, &dummy, &dummy) ;
- v_gtext(handle, x0 + d->x_max_systems * zoom,
- y0 + (y_min - d->dy_note) * zoom,
- itoa(max_time/d->time_per_system * d->bars_per_system, text, 10)) ;
- vswr_mode(handle, MD_REPLACE) ;
- y_max += d->dy_system ; y_min = y_max ;
- }
- }
-
-
- int page_layouter(int handle, int width, int height, Awindow *wi)
- {
- DRAWER *d = wi->user ;
- int index_width, index_height, headline_width, headline_height ;
- char number_of_lines, first_modulo_0 ;
- int first_active_track, last_active_track ;
- PAGE_DESCRIPTOR *page ;
- int p ; /* page number */
- int t ; /* track number */
- float y ; /* current y value */
- NOTE min_note, max_note, note_of_y ;
- TIME time, max_time ;
- int dummy, hor_lines ;
-
- /*** get maximum area allowed for whole drawing ***/
- d->x_min = ((long)(width - 1)) *
- get_left_border(d->params_wi) / 100 ;
- d->x_max = ((long)(width - 1)) *
- (100 - get_right_border(d->params_wi)) / 100 ;
- d->y_min = ((long)(height - 1)) *
- get_upper_border(d->params_wi) / 100 ;
- d->y_max = ((long)(height - 1)) *
- (100 - get_lower_border(d->params_wi)) / 100 ;
-
- /*** check for plausability ***/
- if ( (d->x_min >= d->x_max) || (d->y_min >= d->y_max) )
- {
- alert_str(INVALID_BORDER_VALUES, "") ;
- d->npgs = 0 ;
- return LAYOUT_ERR ;
- }
-
- /*** times, bars ***/
- d->beats_per_system = ((float)get_system_length(d->params_wi))/2 ;
- d->time_per_system = d->beats_per_system *
- get_ticks_per_beat(d->info_wi) ;
- d->bars_per_system = get_bars_per_system(d->params_wi) ;
- d->bar_divider = get_bar_divider(d->params_wi) ;
-
- /*** get y-distances ***/
- d->dy_system = ((float)height * get_system_distance(d->params_wi)) / 100 ;
- d->dy_track = ((float)height * get_track_distance(d->params_wi)) / 100 ;
- d->dy_note = ((float)height * get_note_distance(d->params_wi)) / 1000 ;
- hor_lines = get_hor_lines(d->params_wi) ;
- switch (hor_lines)
- {
- case 1: d->dy_line = d->dy_note * 12 ; break ;
- case 2: d->dy_line = d->dy_note * 6 ; break ;
- case 3: d->dy_line = d->dy_note * 4 ; break ;
- case 4:
- case 5: d->dy_line = d->dy_note * 3 ; break ;
- default: d->dy_line = d->dy_note * 2 ;
- }
-
- /*** get font and its attributes ***/
- d->font_id = get_font_id(d->params_wi) ;
- if ( d->font_id != vst_font(handle, d->font_id) )
- {
- alert_str(FONT_NOT_EXISTING, "") ;
- d->npgs = 0 ;
- return LAYOUT_ERR ;
- }
- /*** note: actual index_height needs not to be desired height ***/
- vst_height(handle, 4 * d->dy_note,
- &index_width, &index_height, &dummy, &dummy) ;
- /*** note: actual headline_height needs not to be HEADLINE_HEIGHT ! ***/
- vst_height(handle, d->dy_system/HEADLINE_DIVIDER,
- &headline_width, &headline_height, &dummy, &dummy) ;
-
- /*** get maximum area allowed for drawing note systems ***/
- d->x_min_systems = d->x_min + INDEX_CHARACTERS * index_width ;
- d->x_max_systems = d->x_max ;
- d->y_min_systems = d->y_min + d->dy_system + headline_height/2 ;
- d->y_max_systems = d->y_max ;
-
- /*** get x-distances ***/
- d->dx_bars = ((float)(d->x_max_systems - d->x_min_systems)) /
- d->bars_per_system ;
-
- /*** tracks ***/
- first_active_track = get_first_active_track(d->filter_wi) ;
- last_active_track = get_last_active_track(d->filter_wi) ;
- if ( (first_active_track < 0) || (last_active_track < 0) )
- {
- alert_str(ALL_TRACKS_OFF, "") ;
- d->npgs = 0 ;
- return LAYOUT_ERR ;
- }
-
- /*** layout all pages ***/
- p = 0 ; d->npgs = 1 ;
- page = d->page ;
- page[p].min_time = 0 ;
- page[p].type = NONE ;
- page[p].number_of_systems = 0 ;
- page[p].first_track = first_active_track ;
- t = first_active_track ;
- y = d->y_min_systems ;
- time = 0 ;
- max_time = get_absolute_max_time(d->filter_wi) ;
-
- while ( (time < max_time) && (p < MAX_PAGES - 1) )
- {
- /*** layout one system ***/
- while ( (t <= last_active_track) &&
- (time < max_time) && (p < MAX_PAGES - 1) )
- {
- if (page[p].type & SUCCEEDING) y += d->dy_track ;
- while ( (y <= d->y_max_systems) && (t <= last_active_track) )
- {
- /*** if this track is active ***/
- if (get_min_max(d->filter_wi, t,
- time, time + d->time_per_system,
- &min_note, &max_note))
- {
- expand(hor_lines, min_note, max_note,
- ¬e_of_y, &number_of_lines, &first_modulo_0) ;
- /*** fits each track into the allowed y-range of a page ? ***/
- if (d->dy_line * (number_of_lines - 1) >
- d->y_max_systems - d->y_min_systems - 2 * d->dy_track)
- {
- alert_str(TRACK_TOO_HIGH, "") ;
- d->npgs = p ;
- return LAYOUT_ERR ;
- }
- y += d->dy_line * (number_of_lines - 1) ;
- y += d->dy_track ;
- }
- t ++ ;
- }
- t -- ;
- if (y > d->y_max_systems)
- {
- /*** the current note system does not fit onto this page ***/
- if (page[p].number_of_systems == 0)
- {
- /*** this is the first system for this page ***/
- page[p].type |= PRECEEDING ;
- page[p].last_track = t - 1 ;
- page[p].number_of_systems = 1 ; /* but not a whole system */
- y = d->y_min_systems ;
- p ++ ; d->npgs ++ ;
- page[p].type = SUCCEEDING ;
- page[p].first_track = t ;
- page[p].number_of_systems = 0 ;
- }
- else
- {
- /*** there are already one or more systems on this page ***/
- y = d->y_min_systems ;
- p ++ ; d->npgs ++ ;
- page[p].type = NONE ;
- t = page[p].first_track = first_active_track ;
- page[p].number_of_systems = 0 ;
- }
- page[p].min_time = time ;
- }
- else
- {
- /*** the current note system fits onto this page ***/
- time += d->time_per_system ;
- t = first_active_track ;
- if (page[p].type == SUCCEEDING)
- {
- /*** one and only system for this page, take a new page ***/
- page[p].last_track = last_active_track ;
- page[p].number_of_systems = 1 ; /* but not a whole system */
- y = d->y_min_systems ;
- p ++ ; if (time < max_time) d->npgs ++ ;
- page[p].type = NONE ;
- page[p].first_track = first_active_track ;
- page[p].last_track = first_active_track ;
- page[p].number_of_systems = 0 ;
- page[p].min_time = time ;
- }
- else
- {
- /*** one more system for this page ***/
- page[p].type = MULTIPLE ;
- page[p].last_track = last_active_track ;
- page[p].number_of_systems ++ ;
- y += (d->dy_system - d->dy_track) ;
- page[p+1].type = NONE ;
- page[p+1].first_track = first_active_track ;
- }
- }
- }
- }
- if (d->current_page > d->npgs - 1) d->current_page = d->npgs - 1 ;
- if (d->npgs >= MAX_PAGES - 1)
- {
- alert_str(MAX_PAGES_REACHED, "" ) ;
- }
- return LAYOUT_GOOD ;
- }
-
-
- void reset_layout(Awindow *wi)
- {
- DRAWER *d = wi->user ;
- page_layouter(d->handle, d->width, d->height, wi) ;
- }
-
-
- void DRAWER_destructor(Awindow *wi)
- {
- if (wi)
- {
- memory_symptom = "DrDstr wi->user" ;
- if (wi->user) My_free(wi->user) ;
- memory_symptom = "DrDstr wi" ;
- Awi_delete(wi) ;
- }
- }
-
-
- Awindow *DRAWER_constructor(DRAWER_INIT *drawer_init)
- {
- Awindow *wi ;
- DRAWER *d ;
-
- /*** enter filename into icon text and info line ***/
- DRAWER_WINDOW.iconblk = drawer_init->icon ;
- DRAWER_WINDOW.iconblk->monoblk.ib_ptext = drawer_init->filename ;
- DRAWER_WINDOW.info = drawer_init->filename ;
-
- /*** create the DRAWER window ***/
- wi = Awi_create(&DRAWER_WINDOW) ;
- if (!wi) return NULL ;
-
- /*** allocate drawer structure and initialize ***/
- wi->user = d = My_alloc(sizeof *d) ;
- if (!d) { DRAWER_destructor(wi) ; return NULL ; }
- d->handle = drawer_init->handle ;
- d->obj_wi = drawer_init->obj_wi ;
- d->obj = drawer_init->obj ;
- d->width = drawer_init->width ;
- d->height = drawer_init->height ;
- d->params_wi = drawer_init->params_window ;
- d->filter_wi = drawer_init->filter_window ;
- d->info_wi = drawer_init->info_window ;
- d->ntrks = get_number_of_tracks(drawer_init->info_window) ;
- d->current_page = 0 ;
- d->npgs = 0 ;
-
- /*** draw at once ***/
- redraw(wi) ;
-
- /*** return success message ***/
- return wi ;
- }
-
-